#include "head.h"

// 用于从服务器下载文件到客户端指定的路径，会检查目录文件是否存在，如果存在则支持断点续传，否则从头开始瞎子啊
// const char  *filename：客户端指定的目标文件路径
int getsFunc(int sockfd, const char *filename) {
    // 这里我必须接收一个整数
    // 可以再发一次数据

    // train_name_t train_name;
    // bzero(&train_name, sizeof(train_name));

    // 下面开始接收数据
    // 先判断是不是断点续传
    
    //train_name_t train_name;
    //bzero(&train_name, sizeof(train_name));
    
    printf("download begin\n");
    off_t offset = 0;
    // 使用 access 函数会检查目标文件是否存在：
    //              1）如果文件存在，使用stat获取文件大小，并将文件大小（offset）发送给服务器
    //              2）如果文件不存在，发送0给服务器，表示需要从头开始下载
    if (access(filename, F_OK) == 0) {
        // 文件存在
        // 这里要告诉他文件存在了
        //train_name_t train_name;
        // 用stat获取文件大小
        struct stat st;

        stat(filename, &st);
        
        //train_name.offset = st.st_size;
        
        //train_name.offset
        offset = st.st_size; // offset为当前客户端文件大小，以便后续断点继续传送
        send(sockfd, &offset, sizeof(off_t), MSG_NOSIGNAL);

        // 接收服务器响应
        int ifErrorNum;
        recvn(sockfd, &ifErrorNum, sizeof(int));
        if (ifErrorNum != 0) {
            print_network_message(sockfd);
            return -1;
        }
        /*int ifError;
          recv(sockfd, &ifError, sizeof(int), 0);
          if (ifError != 0) {
        // 接收一个小ents 火车
        print_network_message(sockfd);
        return -1;
        }*/

        train_t train_file; // 用于接收服务器发送的数据块
        int fd = open(filename, O_WRONLY|O_CREAT, 0666);
        
        // lseek(fd, (off_t)train_name.offset, SEEK_SET);
        
        // 使用lseek 函数将文件定位到 offset位置，以便从上次下载的位置继续写入数据
        lseek(fd, offset, SEEK_SET);

        // 接收文件数据
        while(1){
            bzero(&train_file, sizeof(train_file)); // 清0
            //printf("bzero over\n");
            recvn(sockfd, &train_file.length, sizeof(train_file.length));
            if(train_file.length==0){ // 若接收数据块大小为0，则表示服务器数据传输完成，客户端停止接收
                printf("download over.\n");
                break;
            }
            // 客户端把从服务器接收的数据读出来，并写道本地磁盘中
            // recvn(sockfd, &train_file.offset,sizeof(train_file.offset));
            recvn(sockfd, train_file.data, train_file.length);
            write(fd, train_file.data, train_file.length);
        }
    } else {
        // 若是文件不存在客户端中，则从零开始接收服务器的数据
        off_t offset = 0;
        send(sockfd, &offset, sizeof(off_t), 0);
        /*int ifError;
          recv(sockfd, &ifError, sizeof(int), 0);
          if (ifError != 0) {
        // 接收一个小火车
        print_network_message(sockfd);
        return -1;
        }*/

        // 上边是报错
        // 开始传输
        // 注意open操作的第二个参数
        int ifErrorNum;
        recvn(sockfd, &ifErrorNum, sizeof(int));
        if (ifErrorNum != 0) {
            print_network_message(sockfd);
            return -1;
        }
        train_t train_file;
        int fd = open(filename, O_WRONLY|O_CREAT, 0666);
        // 注意这里TRUNC是不是多余的
        //
        //
        //
        //
        // 对返回的fd做报错分析
        while(1){
            bzero(&train_file, sizeof(train_file));
            //printf("bzero over\n");
            recvn(sockfd, &train_file.length, sizeof(train_file.length));
            if(train_file.length==0){
                printf("download over.\n");
                break;
            }
            // recvn(sockfd, &train_file.offset,sizeof(train_file.offset));
            recvn(sockfd, train_file.data, train_file.length);
            write(fd, train_file.data, train_file.length);
        }
    }
    return 0;
}

// int getsFunc(int sockfd, const char *filename) {
//     // 这里我必须接收一个整数
//     // 可以再发一次数据
// 
//     // train_name_t train_name;
//     // bzero(&train_name, sizeof(train_name));
// 
//     // 下面开始接收数据
//     // 先判断是不是断点续传
//     train_name_t train_name;
//     bzero(&train_name, sizeof(train_name));
//     if (access(filename, F_OK) == 0) {
//         // 文件存在
//         // 这里要告诉他文件存在了
//         //train_name_t train_name;
//         // 用stat获取文件大小
//         struct stat st;
// 
//         stat(filename, &st);
//         train_name.offset = st.st_size;
//         //train_name.offset
// 
//         send(sockfd, &train_name, 2*sizeof(int)+train_name.length, 0);
// 
//         int ifError;
//         recv(sockfd, &ifError, sizeof(int), 0);
//         if (ifError != 0) {
//             // 接收一个小火车
//             print_network_message(sockfd);
//             return -1;
//         }
// 
//         train_t train_file;
//         int fd = open(filename, O_WRONLY | O_APPEND, 0666);
//         // 对返回的fd做报错分析
//         while(1){
//             bzero(&train_file, sizeof(train_file));
//             recvn(sockfd, &train_file.length, sizeof(train_file.length));
//             if(train_file.length==0){
//                 break;
//             }
//             recvn(sockfd, train_file.data, train_file.length);
//             write(fd, train_file.data, train_file.length);
//         }
//     } else {
//         train_name.offset = 0;    
//         send(sockfd, &train_name, 2*sizeof(int)+train_name.length, 0);
//         int ifError;
//         recv(sockfd, &ifError, sizeof(int), 0);
//         if (ifError != 0) {
//             // 接收一个小火车
//             print_network_message(sockfd);
//             return -1;
//         }
// 
//         // 上边是报错
//         // 开始传输
//         // 注意open操作的第二个参数
//         train_t train_file;
//         int fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0666);
//         // 注意这里TRUNC是不是多余的
//         //
//         //
//         //
//         //
//         // 对返回的fd做报错分析
//         while(1){
//             bzero(&train_file, sizeof(train_file));
//             recvn(sockfd, &train_file.length, sizeof(train_file.length));
//             if(train_file.length==0){
//                 break;
//             }
//             recvn(sockfd, train_file.data, train_file.length);
//             write(fd, train_file.data, train_file.length);
//         }
// 
// 
//     }
//     return 0;
// }
